/* eslint-disable jsdoc/check-tag-names */
'use strict';
/**
* @controller cw_sys 系统管理
*/
const Controller = require('./base');
const { Op } = require('sequelize');
class CwSysController extends Controller {
  /**
* @summary 获取用户信息
* @description 登录后获取用户的登录信息
* @router get /adminApi/cw_sys/currentUser
* @request header string token 用户token
* @response 200 baseResponse 用户信息
*/
  async currentUser() {
    const { ctx } = this;
    const userInfo = await ctx.model.CwUser.findOne({ attributes: { exclude: [ 'password' ] }, where: { id: ctx.userInfo.id } });
    userInfo.dataValues.roleIds = await ctx.service.cwRbac.getRoleIds(userInfo.id);
    this.success(userInfo);
  }
  /**
  * @summary 组织列表
  * @description 组织列表
  * @router get /adminApi/cw_sys/orgList
  * @request header string token 用户token
  * @request query string t 如果有值返回全树
  * @response 200 baseResponse desc
  */
  async orgList() {
    const { t } = this.ctx.query;
    const map = {};
    map.order = [
      [ 'sort', 'ASC' ],
    ];
    map.attributes = [
      'id', [ 'id', 'key' ], [ 'name', 'title' ], 'pid', 'desc', 'sort', 'name',
    ];
    const list = await this.ctx.model.CwOrg.findAll(map);
    const expandAll = list.map(o => o.id);
    const tree = this.ctx.helper.cw.arr_to_tree(list, 0);
    let res;
    if (!this.ctx.helper.cw._.isEmpty(t)) {
      res = [{ title: '一级组织', key: 0 }, ...tree ];
    } else {
      res = {
        tree,
        expandAll,
      };
    }
    this.success(res);
  }
  /**
  * @summary 添加组织
  * @description 添加组织
  * @router post /adminApi/cw_sys/addOrg
  * @request header string token 用户token
  * @request body addOrgRequest *body desc
  * @response 200 baseResponse desc
  */
  async addOrg() {
    const data = this.ctx.request.body;
    const add = await this.ctx.model.CwOrg.create(data);
    this.success(add);
  }
  /**
  * @summary 编辑组织
  * @description 编辑组织
  * @router post /adminApi/cw_sys/editOrg
  * @request header string token 用户token
  * @request body orgItem *body desc
  * @response 200 baseResponse desc
  */
  async editOrg() {
    const data = this.ctx.request.body;
    if (!data.id) return this.fail('缺少id');
    const edit = await this.ctx.model.CwOrg.update(data, { where: { id: data.id } });
    this.success(edit);
  }
  /**
  * @summary 删除组织
  * @description 删除组织
  * @router get /adminApi/cw_sys/delOrg
  * @request header string token 用户token
  * @request query integer *id id
  * @response 200 baseResponse desc
  */
  async delOrg() {
    const id = this.ctx.query.id;
    if (!id) return this.fail('缺少id');
    const del = await this.ctx.model.CwOrg.destroy({ where: { id } });
    await this.ctx.model.CwOrg.destroy({ where: { pid: id } });
    this.success(del);
  }
  /**
  * @summary 组织拖动排序
  * @description 组织拖动排序
  * @router post /adminApi/cw_sys/dropOrg
  * @request header string token 用户token
  * @request body orgItem *body desc
  * @response 200 baseResponse desc
  */
  async dropOrg() {
    const data = this.ctx.request.body;
    const arrtodata = function(data, pid, result = []) {
      const length = data.length;
      for (let i = 0; i < length; i++) {
        data[i].pid = pid;
        data[i].sort = i;
        result.push(data[i]);
        if (data[i].children) {
          arrtodata(data[i].children, data[i].id, result);
        }
      }
      return result;
    };
    const d = arrtodata(data, 0, []);
    for (const v of d) {
      await this.ctx.model.CwOrg.update({ pid: v.pid, sort: v.sort }, { where: { id: v.id } });
    }
    this.success(1);
  }
  /**
  * @summary 获取角色列表
  * @description 获取角色列表
  * @router get /adminApi/cw_sys/roleList
  * @request header string token 用户token
  * @request query string *current current
  * @request query string *pageSize pageSize
  * @request query string name name
  * @request query string state state
  * @request query string desc desc
  * @request query string sorter sorter
  * @response 200 baseResponse desc
  */
  async roleList() {
    const { current, pageSize, name, state, desc, sorter } = this.ctx.query;
    const map = {};
    map.offset = (Number(current) - 1) * Number(pageSize);
    map.limit = Number(pageSize);
    map.where = {};
    if (name) {
      map.where.name = { [Op.like]: `%${name}%` };
    }
    if (desc) {
      map.where.desc = { [Op.like]: `%${desc}%` };
    }
    if (state && state !== 'all') {
      map.where.state = state === 'true';
    }
    // map.order = [[ 'updatedAt', 'DESC' ]];
    if (sorter !== '{}') {
      const order = JSON.parse(sorter);
      const px = Object.keys(order);
      const pv = order[px[0]] === 'ascend' ? 'ASC' : 'DESC';
      map.order = [[ px[0], pv ]];
    }
    // console.log(map);
    const res = await this.ctx.model.CwRole.findAndCountAll(map);
    // console.log(JSON.stringify(res, null, 2));
    this.ctx.body = { success: true, data: res.rows, total: res.count };
  }
  /**
  * @summary 添加角色
  * @description 添加角色
  * @router post /adminApi/cw_sys/addRole
  * @request header string token 用户token
  * @request body addRoleRequest *body desc
  * @response 200 baseResponse desc
  */
  async addRole() {
    const data = this.ctx.request.body;
    data.menu_ids = data.menu_ids.join(',');
    data.checkedKeysValue = data.checkedKeysValue.join(',');
    data.halfCheckedKeys = data.halfCheckedKeys.join(',');
    // data.state = data.state === 1;
    // console.log(data);
    const add = await this.ctx.model.CwRole.create(data);
    this.success(add);
  }
  /**
  * @summary 编辑角色
  * @description 编辑角色
  * @router post /adminApi/cw_sys/editRole
  * @request header string token 用户token
  * @request body roleTtem *body desc
  * @response 200 baseResponse desc
  */
  async editRole() {
    const data = this.ctx.request.body;
    if (!data.id) return this.fail('缺少id');
    data.menu_ids = data.menu_ids.join(',');
    data.checkedKeysValue = data.checkedKeysValue.join(',');
    data.halfCheckedKeys = data.halfCheckedKeys.join(',');
    const edit = await this.ctx.model.CwRole.update(data, { where: { id: data.id } });
    this.success(edit);
  }
  /**
  * @summary 删除角色
  * @description 删除角色
  * @router get /adminApi/cw_sys/delRole
  * @request header string token 用户token
  * @request query integer *id id
  * @response 200 baseResponse desc
  */
  async delRole() {
    const id = this.ctx.query.id;
    if (!id) return this.fail('缺少id');
    const del = await this.ctx.model.CwRole.destroy({ where: { id } });
    await this.ctx.model.CwUserRole.destroy({ where: { role_id: id } });
    this.success(del);
  }
  /**
  * @summary 获取全部树路由节点
  * @description 获取全部树路由节点
  * @router get /adminApi/cw_sys/roleNode
  * @request header string token 用户token
  * @request query integer *mod_id 模块id
  * @response 200 baseResponse errorCode:0成功
  */
  async roleNode() {
    const { ctx } = this;
    const { mod_id } = ctx.query;
    const { cw } = ctx.helper;
    const map = {};
    map.order = [[ 'sort', 'ASC' ]];
    map.where = {};
    map.where.mod_id = mod_id;
    map.where.role = true;
    map.attributes = { exclude: [ 'role' ] };
    const list = await ctx.model.CwMenu.findAll(map);
    const tree = cw.arr_to_tree(list, 0);
    this.success(tree);
  }
  /**
  * @summary 获取角色详情
  * @description 获取角色详情
  * @router get /adminApi/cw_sys/showRole
  * @request header string token 用户token
  * @request query integer *id 角色id
  * @response 200 baseResponse errorCode:0成功
  */
  async showRole() {
    const { id } = this.ctx.query;
    // console.log(this.ctx.query.id);
    const map = {};
    map.where = {};
    map.where.id = id;
    const info = await this.ctx.model.CwRole.findOne(map);
    const nodes = await this.ctx.model.CwMenu.findAll({ where: { id: { [Op.in]: info.menu_ids.split(',').map(Number) } }, attributes: { exclude: [ 'role' ] } });
    info.dataValues.tree = this.ctx.helper.cw.arr_to_tree(nodes, 0);
    this.success(info);
  }
  /**
  * @summary 获取用户列表
  * @description 获取用户列表
  * @router get /adminApi/cw_sys/userList
  * @request header string token 用户token
  * @response 200 userListResponse desc
  */
  async userList() {
    const { current, pageSize, username, mobile, email, sorter, org_id, filter } = this.ctx.query;
    // 获取上级id
    let pids;
    if (org_id !== 'all') {
      const dd = await this.ctx.model.CwOrg.findAll();
      if (dd) {
        pids = this.ctx.helper.cw.sub_ids(dd, Number(org_id));
        pids.push(Number(org_id));
      }
    }
    const map = {};
    map.offset = (Number(current) - 1) * Number(pageSize);
    map.limit = Number(pageSize);
    map.where = {};
    if (pids) {
      map.where.org_id = { [Op.in]: pids };
    }
    if (username) {
      map.where.username = { [Op.like]: `%${username}%` };
    }
    if (email) {
      map.where.email = { [Op.like]: `%${email}%` };
    }
    if (mobile) {
      map.where.mobile = { [Op.like]: `%${mobile}%` };
    }
    const f = JSON.parse(filter);
    if (f.state && f.state.length === 1) {
      map.where.state = f.state[0] === 'true';
    }
    map.include = [{
      model: this.ctx.model.CwRole,
      attributes: [
        [ 'id', 'value' ],
        [ 'name', 'label' ],
        [ 'id', 'key' ],
      ],
      // required: true,
    }, {
      model: this.ctx.model.CwOrg,
    }];
    if (f.cw_roles) {
      map.include[0].where = {};
      map.include[0].where.id = { [Op.in]: f.cw_roles };
    }
    map.order = [[ 'id', 'DESC' ]];
    if (sorter && sorter !== '{}') {
      const order = JSON.parse(sorter);
      const px = Object.keys(order);
      const pv = order[px[0]] === 'ascend' ? 'ASC' : 'DESC';
      map.order = [[ px[0], pv ]];
    }
    // console.log(map);
    const res = await this.ctx.model.CwUser.findAndCountAll(map);
    // console.log(JSON.stringify(res, null, 2));
    this.ctx.body = { success: true, data: res.rows, total: res.count };
  }
  /**
  * @summary 添加用户
  * @description 添加用户
  * @router post /adminApi/cw_sys/addUser
  * @request header string token 用户token
  * @request body userItem *body desc
  * @response 200 baseResponse desc
  */
  async addUser() {
    const data = this.ctx.request.body;
    data.password = this.ctx.helper.cw.cipher(data.password);
    // console.log(data);
    try {
      const result = await this.ctx.model.transaction(async t => {
        const [ user, created ] = await this.ctx.model.CwUser.findOrCreate({
          where: { username: data.username },
          defaults: data,
          transaction: t });
        // console.log(user, created);
        if (!created) throw new Error('用户名已经存在');
        await this.ctx.model.CwUserRole.destroy({ where: { user_id: user.id }, transaction: t });
        if (!data.admin && data.role_ids.length > 0) {
          for (const v of data.role_ids) {
            await this.ctx.model.CwUserRole.create({ user_id: user.id, role_id: v.value }, { transaction: t });
          }
        }
        // throw new Error('fdsafsda');
        return user;
      });
      this.success(result);
      // If the execution reaches this line, the transaction has been committed successfully
      // `result` is whatever was returned from the transaction callback (the `user`, in this case)

    } catch (error) {
      // console.log(error.toString());
      this.fail(error.toString());
      // If the execution reaches this line, an error occurred.
      // The transaction has already been rolled back automatically by Sequelize!

    }
  }
  /**
  * @summary 编辑用户
  * @description 编辑用户
  * @router post /adminApi/cw_sys/editUser
  * @request header string token 用户token
  * @request body userItem *body desc
  * @response 200 baseResponse desc
  */
  async editUser() {
    const data = this.ctx.request.body;
    if (data.password) {
      data.password = this.ctx.helper.cw.cipher(data.password);
    }
    data.org_id = data.org_id ? data.org_id : 0;
    try {
      const result = await this.ctx.model.transaction(async t => {
        const find = await this.ctx.model.CwUser.findOne({
          where: {
            username: { [Op.eq]: data.username },
            id: { [Op.ne]: data.id },
          },
        });
        if (find) throw new Error('用户名已经存在');
        const user = await this.ctx.model.CwUser.update(data, {
          where: { id: data.id },
          transaction: t });
        await this.ctx.model.CwUserRole.destroy({ where: { user_id: data.id }, transaction: t });
        if (!data.admin && data.role_ids.length > 0) {
          for (const v of data.role_ids) {
            await this.ctx.model.CwUserRole.create({ user_id: data.id, role_id: v.value }, { transaction: t });
          }
        }
        // throw new Error('fdsafsda');
        return user;
      });
      this.success(result);
      // If the execution reaches this line, the transaction has been committed successfully
      // `result` is whatever was returned from the transaction callback (the `user`, in this case)

    } catch (error) {
      // console.log(error.toString());
      this.fail(error.toString());
      // If the execution reaches this line, an error occurred.
      // The transaction has already been rolled back automatically by Sequelize!

    }
  }
  /**
  * @summary 删除用户
  * @description 删除用户
  * @router get /adminApi/cw_sys/delUser
  * @request header string token 用户token
  * @request query integer *id 用户id
  * @response 200 baseResponse desc
  */
  async delUser() {
    const id = this.ctx.query.id;
    if (!id) return this.fail('缺少id');
    await this.ctx.model.CwUser.destroy({ where: { id } });
    await this.ctx.model.CwUserRole.destroy({ where: { user_id: id } });
    this.success(1);
  }
  /**
  * @summary 获取所有角色
  * @description 获取所有角色
  * @router get /adminApi/cw_sys/getAllRole
  * @request header string token 用户token
  * @response 200 baseResponse desc
  */
  async getAllRole() {
    const map = {};
    map.where = {};
    map.where.state = 1;
    map.order = [[ 'updatedAt', 'DESC' ]];
    map.attributes = [
      [ 'id', 'value' ],
      [ 'name', 'label' ],
      [ 'id', 'key' ],
    ];
    // console.log(map);
    const res = await this.ctx.model.CwRole.findAll(map);
    // console.log(JSON.stringify(res, null, 2));
    this.success(res);
  }
}

module.exports = CwSysController;
